import os  # 导入 os 模块，用于操作系统相关的操作
import re  # 导入 re 模块，用于正则表达式匹配
import subprocess  # 导入 subprocess 模块，用于执行系统命令

# 定义映射关系
mapping = {
    '01': '产品',  # 文件名前缀 '01' 对应 '产品'
    'm001': '机构管理',  # 文件名前缀 'm001' 对应 '机构管理'
    'f': '查询'  # 文件名前缀 'f' 对应 '查询'
}


def map_filename(filename):
    """
    根据映射关系将文件名映射为对应的名称。

    参数:
    filename (str): 需要映射的文件名

    返回:
    str: 映射后的文件名，如果无法映射则返回 None
    """
    # 定义文件名格式的正则表达式
    pattern = r'^(\d{2})([a-zA-Z])(\d{3})([a-zA-Z])_.*\.txt$'
    match = re.match(pattern, filename)

    if not match:
        return None  # 如果文件名不符合格式，返回 None

    # 提取文件名中的各个部分
    prefix1, prefix2, prefix3 = match.group(1), match.group(2) + match.group(3), match.group(4)

    # 构建映射后的文件名
    mapped_name = ''
    if prefix1 in mapping:
        mapped_name += mapping[prefix1]
    if prefix2 in mapping:
        mapped_name += mapping[prefix2]
    if prefix3 in mapping:
        mapped_name += mapping[prefix3]

    if not mapped_name:
        return None  # 如果映射后的文件名为空，返回 None

    return f"{mapped_name}.txt"  # 返回映射后的文件名，加上 .txt 扩展名


base = 'python3 sqlmap.py -r'  # 定义基本命令前缀
end = '--batch --flush-session'  # 定义命令的结束部分
file = input('需要执行的文件列表（所有输入all）:')  # 获取用户输入的文件列表或 'all'

try:
    # 尝试将输入转换为列表
    file_list = eval(file)

    # 检查是否为列表
    if not isinstance(file_list, list):
        raise ValueError("输入必须是一个列表")  # 如果不是列表，抛出 ValueError

    # 检查列表中的每个元素是否为字符串
    for item in file_list:
        if not isinstance(item, str):
            raise ValueError("列表中的每个元素必须是字符串")  # 如果元素不是字符串，抛出 ValueError

    for i in file_list:  # 遍历文件列表
        mapped_name = map_filename(i)  # 调用 map_filename 函数映射文件名
        if mapped_name is None:  # 如果无法映射文件名
            print(f"无法映射文件名: {i}")  # 输出提示信息
            continue  # 跳过当前文件

        report_path = f"./report/{mapped_name}"  # 构建报告文件路径
        s = f"{base} ./json/{i} {end} > {report_path}"  # 构建完整的命令
        print(s)  # 输出命令

        # 使用 subprocess.run 执行命令
        result = subprocess.run(s, shell=True, check=True, text=True, capture_output=True)
        print(result.stdout)  # 输出命令的标准输出
        if result.stderr:
            print(result.stderr)  # 输出命令的标准错误

except NameError:
    print("输入无效，请输入一个有效的列表，例如 ['file1.txt', 'file2.txt']")  # 捕获 NameError 并输出提示信息
except ValueError as ve:
    print(ve)  # 捕获 ValueError 并输出错误信息
except subprocess.CalledProcessError as cpe:
    print(f"命令执行失败: {cpe.stderr}")  # 捕获命令执行错误并输出错误信息
else:
    # 处理 "all" 的情况
    if file.upper() == 'ALL':  # 如果用户输入 'all'
        json_folder = './json/'  # 定义 JSON 文件夹路径
        if os.path.exists(json_folder) and os.path.isdir(json_folder):  # 检查文件夹是否存在且是目录
            files = os.listdir(json_folder)  # 获取文件夹中的所有文件
            for i in files:  # 遍历文件列表
                mapped_name = map_filename(i)  # 调用 map_filename 函数映射文件名
                if mapped_name is None:  # 如果无法映射文件名
                    print(f"无法映射文件名: {i}")  # 输出提示信息
                    continue  # 跳过当前文件

                report_path = f"./report/{mapped_name}"  # 构建报告文件路径
                s = f"{base} ./json/{i} {end} > {report_path}"  # 构建完整的命令
                print(s)  # 输出命令

                # 使用 subprocess.run 执行命令
                result = subprocess.run(s, shell=True, check=True, text=True, capture_output=True)
                print(result.stdout)  # 输出命令的标准输出
                if result.stderr:
                    print(result.stderr)  # 输出命令的标准错误
        else:
            print(f"文件夹 {json_folder} 不存在或不是一个目录")  # 如果文件夹不存在或不是目录，输出提示信息

# 确保 report 文件夹存在
if not os.path.exists('./report'):  # 检查 report 文件夹是否存在
    os.makedirs('./report')  # 如果不存在，创建 report 文件夹
